package com.gztms.ordermgnt.service.impl;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.gztms.enums.AppCodeEnum;
import com.gztms.enums.OrderStatus;
import com.gztms.ordermgnt.mapper.OrderMapper;
import com.gztms.ordermgnt.pojo.Order;
import com.gztms.ordermgnt.pojo.VO.OrderVO;
import com.gztms.ordermgnt.service.OrderService;
import com.gztms.travelmgnt.pojo.Attractions;
import com.gztms.travelmgnt.service.AttractionsService;
import com.gztms.usermgnt.pojo.User;
import com.gztms.usermgnt.service.UserService;
import com.gztms.utils.BeanCopyUtils;
import com.gztms.utils.GenerateIdUtil;
import com.gztms.utils.ResultUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.AmqpException;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessagePostProcessor;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * (SysOrder)表服务实现类
 *
 * @author makejava
 * @since 2023-05-02 17:23:47
 */
@Service
@Slf4j
public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements OrderService {
    @Autowired
    private AttractionsService attractionsService;

    @Autowired
    private UserService userService;
    @Autowired
    private RabbitTemplate rabbitTemplate;
    @Value("${mayikt.order.exchange}")
    private String orderExchange; //订单交换机

    @Value("${mayikt.order.routingKey}")
    private String orderRoutingKey; //订单路由key

    @Override
    public ResultUtil addOrder(Order order) {
        // 生成orderId
        GenerateIdUtil GenerateIdUtil = new GenerateIdUtil();
        Long orderId = GenerateIdUtil.nextId();
        order.setId(orderId);
        // price应该是景区的price
        Attractions attraction = attractionsService.getById(order.getAttrId());
        // 判断库存是否为空
        if (attraction.getRemainSum() == 0) {
            return ResultUtil.errorResult(AppCodeEnum.SYSTEM_ERROR.getCode(),"门票已售完！");
        }
        if (attraction.getRemainSum()-order.getCount() <= 0) {
            return ResultUtil.errorResult(AppCodeEnum.SYSTEM_ERROR.getCode(),"购买数量超过限制！");
        }
        order.setPrice(attraction.getPrice());
        // 计算总金额
        BigDecimal totalPrice = order.getPrice().multiply(new BigDecimal(String.valueOf(order.getCount())));
        order.setTotalPrice(totalPrice);
        // 设置订单状态
        order.setStatus(OrderStatus.ORDER_UNPAID);
        // RABBIT传递消息
        rabbitTemplate.convertAndSend(orderExchange,orderRoutingKey,orderId,messagePostProcessor());
        // 存入数据库中
        boolean res = save(order);
        if (!res) {
            return ResultUtil.errorResult(AppCodeEnum.SYSTEM_ERROR.getCode(),"服务器错误，创建订单失败！");
        }
        // 减去库存
        attraction.setRemainSum(attraction.getLimitPerson()-order.getCount());
        Map<String,Object> map = new HashMap<>();
        map.put("orderId", StrUtil.toString(orderId));
        return ResultUtil.okResult(map);
    }

    @Override
    public ResultUtil delOrderById(Long id) {
        removeById(id);
        return ResultUtil.okResult();
    }

    @Override
    public ResultUtil delOrderList(List<Long> orderIds) {
        removeByIds(orderIds);
        return ResultUtil.okResult();
    }

    @Override
    public ResultUtil payOrderById(Long id) {
        Order order = new Order();
        order.setId(id);
        order.setStatus(OrderStatus.ORDER_PAID);
        order.setPayTime(new Date());
        updateById(order);
//        update(order,null);
        return ResultUtil.okResult(AppCodeEnum.SUCCESS.getCode(),"支付成功");
    }


    @Override
    public ResultUtil getOrderList(Integer pageNum, Integer pageSize, Integer status, Long id) {
        Page<Order> page = new Page<>(pageNum,pageSize);
        LambdaQueryWrapper<Order> queryWrapper = new LambdaQueryWrapper();
        if (Objects.nonNull(status) && status != OrderStatus.ORDER_ALL) {
            queryWrapper.eq(Order::getStatus,status);
        }
        if (Objects.nonNull(id)) {
            queryWrapper.eq(Order::getId, id);
        }

        queryWrapper.orderByAsc(Order::getCreateTime);
        List<Order> orders = page(page, queryWrapper).getRecords();
        // 将数据封装成OrderVO
        List<OrderVO> orderVOs = BeanCopyUtils.copyBeanList(orders, OrderVO.class);

        // 查询用户名和景区名
        orderVOs.stream()
                .map(orderVO -> {
                    orderVO.setUsername(userService.getById(orderVO.getCreatedBy()).getUsername());
                    orderVO.setAttrName(attractionsService.getById(orderVO.getAttrId()).getName());
                    return orderVO;
                })
                .collect(Collectors.toList());

        Map<String,Object> map = new HashMap<>();
        map.put("orders",orderVOs);
        map.put("total",page.getTotal());
        return ResultUtil.okResult(map);
    }

    @Override
    public ResultUtil getOrderDetail(Long id) {
        Order order = getById(id);
        OrderVO orderVO = toOrderVO(order);
        return ResultUtil.okResult(orderVO);
    }

    @Override
    public List<OrderVO> getOrderListByIds(Long[] orderIds) {
        List<Order> orders = null;
        if (Objects.isNull(orderIds)){
            orders = list();
        } else {
            orders = listByIds(Arrays.asList(orderIds));
        }
        orders.stream()
                .map( order -> toOrderVO(order))
                .collect(Collectors.toList());
        List<OrderVO> orderVOS = BeanCopyUtils.copyBeanList(orders, OrderVO.class);
        return orderVOS;
    }

    @Override
    public List<OrderVO> getAllOrders() {

        List<Order> orders = list();
        List<OrderVO> orderVOS = BeanCopyUtils.copyBeanList(orders, OrderVO.class);
        orderVOS.stream()
                .map(new Function<OrderVO, Object>() {
                    @Override
                    public Object apply(OrderVO orderVO) {
                        orderVO.setUsername(userService.getById(orderVO.getCreatedBy()).getUsername());
                        orderVO.setAttrName(attractionsService.getById(orderVO.getAttrId()).getName());
                        return orderVO;
                    }
                })
                .collect(Collectors.toList());
        System.out.println("ordervos:"+ orderVOS);
        return orderVOS;
    }

    @Override
    public ResultUtil getOrdersByUid(Integer pageNum, Integer pageSize, Integer status, String uid) {
        Page<Order> page = new Page<>(pageNum,pageSize);
        LambdaQueryWrapper<Order> queryWrapper = new LambdaQueryWrapper();
        queryWrapper.eq(Order::getCreatedBy,uid);
        if (Objects.nonNull(status) && status != OrderStatus.ORDER_ALL) {
            queryWrapper.eq(Order::getStatus,status);
        }

        Page<Order> orderPage = page(page, queryWrapper);
        List<Order> orders = orderPage.getRecords();

        List<OrderVO> orderVOS = toOrderVOs(orders);
        Map<String,Object> map = new HashMap<>();
        map.put("orders", orderVOS);
        map.put("total",orderPage.getTotal());
        return new ResultUtil(ResultUtil.SUCCESS,"查询成功",map);
    }


    private MessagePostProcessor messagePostProcessor() {
        return new MessagePostProcessor() {
            @Override
            public Message postProcessMessage(Message message) throws AmqpException {
                // 设置有效期30min
                message.getMessageProperties().setExpiration("1800000");
                // 测试用
//                message.getMessageProperties().setExpiration("10000");
                return message;
            }
        };
    }

    private OrderVO toOrderVO(Order order) {
        OrderVO orderVO = BeanCopyUtils.copyBean(order, OrderVO.class);
        orderVO.setUsername(userService.getById(orderVO.getCreatedBy()).getUsername());
        orderVO.setAttrName(attractionsService.getById(orderVO.getAttrId()).getName());
        return orderVO;
    }

    private List<OrderVO> toOrderVOs(List<Order> orders) {
        List<OrderVO> orderVOS = BeanCopyUtils.copyBeanList(orders, OrderVO.class);
        orderVOS.stream()
                .map(orderVO -> {
                    orderVO.setUsername(userService.getById(orderVO.getCreatedBy()).getUsername());
                    orderVO.setAttrName(attractionsService.getById(orderVO.getAttrId()).getName());
                    return orderVO;
                })
                .collect(Collectors.toList());

        return orderVOS;
    }


}

